import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class MatrixMultiply
{
    private double[][] matrix1;
    private double[][] matrix2;
    private int row;
    private int column;

    public MatrixMultiply(double[][] matrix1, double[][] matrix2)
    {
        this.matrix1 = Objects.requireNonNullElseGet(matrix1, () -> new double[0][0]);
        this.matrix2 = Objects.requireNonNullElseGet(matrix2, () -> new double[0][0]);
    }

    public double[][] getMatrix1()
    {
        return matrix1;
    }

    public double[][] getMatrix2()
    {
        return matrix2;
    }

    public double[][] multiply() //单线程矩阵乘法
    {
        double[][] result = new double[matrix1.length][matrix2[0].length];
        for (int i = 0; i < result.length; i++)
        {
            for (int j = 0; j < result[0].length; j++)
            {
                result[i][j] = 0.0;
                for (int k = 0; k < matrix1[0].length; k++)
                {
                    result[i][j] += matrix1[i][k] * matrix2[k][j];
                }
            }
        }
        return result;
    }

    public double[][] multiply(int threadCount) //多线程矩阵乘法
    {
        threadCount = Math.max(1, threadCount);
        this.row = 0;
        this.column = 0;
        double[][] result = new double[matrix1.length][matrix2[0].length];
        Thread[] threads = new MatrixMultiplyThread[threadCount];
        for (int i = 0; i < threads.length; i++)
        {
            threads[i] = new MatrixMultiplyThread(MatrixMultiply.this, result);
            threads[i].start();
        }
        for (int i = 0; i < threads.length; i++)
        {
            try
            {
                threads[i].join();
            } catch (InterruptedException e)
            {
                e.printStackTrace();
            }
        }
        return result;
    }

    public synchronized boolean hasNext()
    {
        return !(row == matrix1.length && column == 0);
    }

    public synchronized int[] next()
    {
        if (!hasNext())
            return null;
        int[] result = new int[]{row, column};
        if (column < matrix2[0].length - 1)
        {
            column++;
        }
        else
        {
            row++;
            column = 0;
        }
        return result;
    }
}
